package com.smart.other;


import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Response;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.smart.common.entities.constant.SmartConstant;
import com.smart.manager.finance.entities.enums.PaymentScene;
import com.smart.wap.service.AliPayHandler;
import com.smart.wap.service.PaySuccessHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.EnumUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;

/**
 * 支付回调处理方法
 * @author xiaxuqiu

 */

@RestController
@RequestMapping(SmartConstant.OTHER_API_PREFIX + "payment/callback")
@RequiredArgsConstructor
@Log4j2
public class PaymentCallback {

    private final WxPayService wxPayService;
    private final AliPayHandler aliPayHandler;
    private final HttpServletRequest request;
    private final PaySuccessHandler paySuccessHandler;
    public static final String WECHAT_PAY_SUCCESS = "SUCCESS";
    public static final String ALIPAY_SUCCESS = "TRADE_SUCCESS";

    /**
     * @param appId   app数据主键
     * @return {@link String}
     */
    @ResponseBody
    @PostMapping("wxpay/{appId}/{since}")
    public String wechatCallback( @PathVariable String appId ,@PathVariable String since) throws IOException, WxPayException {
        log.warn("收到微信支付支付回调 appID:{} ,支付场景 {}" ,appId ,since);
        //开始解析并验签微信支付返回的数据
        String data = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());

        log.warn("收到微信支付回调发来的请求 {}" ,data);
        String timeStamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String serial = request.getHeader("Wechatpay-Serial");
        SignatureHeader signatureHeader = new SignatureHeader(timeStamp, nonce, signature, serial);
        WxPayNotifyV3Result.DecryptNotifyResult result = wxPayService.switchoverTo(appId).parseOrderNotifyV3Result(data, signatureHeader).getResult();
        if (WECHAT_PAY_SUCCESS.equals(result.getTradeState())) {
            try {
                int total = result.getAmount().getPayerTotal();
                //实际支付金额
                BigDecimal payAmount = BigDecimal.valueOf(total).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.DOWN);
                PaymentScene paymentScene = EnumUtils.getEnum(PaymentScene.class, since.toUpperCase());
                switch (paymentScene) {
                    case COIN:
                        paySuccessHandler.onCoinSuccess(result.getOutTradeNo(), result.getTransactionId(), payAmount);
                        return WxPayNotifyV3Response.success("OK");
                    case CASH:
                        log.warn("现金充值成功");
                        return WxPayNotifyV3Response.success("OK");
                    case KEEP:
                        log.warn("保证金提交成功");

                        return WxPayNotifyV3Response.success("OK");
                    default:
                        return WxPayNotifyV3Response.fail("无法识别的支付参数");
                }


            } catch (Exception e) {
                log.error("微信支付处理报错 返回参数:{},错误提示:{}", result, e);
            }
        }
        return WxPayNotifyV3Response.fail("支付失败");
    }


    @PostMapping(value = "alipay/{appId}/{since}")
    public String alipayCallback( @PathVariable String appId,@PathVariable String since) {
        log.warn("收到支付宝支付回调 appID:{} ,支付场景 {}" ,appId ,since);
        Map<String, String> paramMap = ServletUtil.getParamMap(request);
        if (!aliPayHandler.checkSign(paramMap)) {
            log.error("支付宝签名异常: {}", paramMap);
            return "failure";
        }

        if (!StrUtil.equals(paramMap.get("trade_status"), ALIPAY_SUCCESS)) {
            log.error("订单数据不正常 不继续流转: {}", paramMap);
            return "failure";
        }

        String outTradeNo = paramMap.get("out_trade_no");
        String transactionId = paramMap.get("trade_no");
        BigDecimal payAmount = new BigDecimal(paramMap.get("total_amount")).setScale(2, RoundingMode.DOWN);
        paySuccessHandler.onCoinSuccess(outTradeNo, transactionId, payAmount);
        PaymentScene paymentScene = EnumUtils.getEnum(PaymentScene.class, since.toUpperCase());
        switch (paymentScene) {
            case COIN:
                paySuccessHandler.onCoinSuccess(outTradeNo, transactionId, payAmount);
                return "success";
            case CASH:
                log.warn("现金充值成功");
                return "success";
            default:
                return "failure";
        }


    }


}
